package cn.com.surker.util;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.poi.ss.formula.functions.T;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatterBuilder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串帮助类
 */
public class StringUtils {

	private static final String[] upNum = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
	private static final String[] danwei = {"圆", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"};

    /**车牌号**/
    private static String carNumber = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领]" +
            "{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$";

    /**新能源**/
    private static String carNewNumber = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]" +
            "{1}[A-Z0-9]{1}(([0-9]{5}[A-Z]$)|([A-Z0-9][A-HJ-NP-Z0-9][0-9]{4}$))";

    /**电话号码验证**/
	private static String phoneNumber = "^1\\d{10}$";

	// 正则表达式，用于匹配18位身份证号码的格式
	private static final String ID_CARD_REGEX = "^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])\\d{3}(\\d|X|x)$";

    /**浮点小数验证**/
    private static String doubleNumber = "^[0-9]+(.[0-9]+)?$";

    /**邮箱验证**/
    private static String email = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";

    /**IP验证**/
    private static String ip = "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}";


    private static String allChar = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static String letterChar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static String nletterchar = "0123456789abcdefghijklmnopqrstuvwxyz";
    private static String numberChar = "0123456789";

    /**
     * json字符转对象
     * @return
     */
    public synchronized static <T> T convertJsonToClazz(String json, Class<T> clazz) {
        if (isNull(json) || clazz == null)
            return null;
        JSONObject object = JSONObject.parseObject(json);
        if (object == null)
            return null;
        T newClazz = object.toJavaObject(object, clazz);
        return newClazz;
    }

    /**
     * 对象转json
     * @return
     */
    public synchronized static JSONObject convertClazzToJson(Object object) {
        if (object == null)
            return null;
        JSONObject obj = JSONObject.parseObject(JSONObject.toJSONString(object));
        return obj;
    }
	/**
	 * 渲染成财务显示的金额
	 *
	 * @param number
	 * @return
	 */
	public synchronized static String financialDisplay(Double number) {
		if (number == null) {
			return "";
		}
		DecimalFormat df = new DecimalFormat("#,##0.00");
		String formatted = df.format(number);
		return formatted;
	}

	/**
     * 判断字符串是否为空
     * @param string
     * @return
     */
    public synchronized static boolean isNull(String string){
        if(string == null || string.equals("")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 标题：isAllParamNull 描述：多个字符串非空检查（只要其中一个为空则返回空）
     * @param param
     * @return true对象为null false对象不为null
     */
    public synchronized static boolean isAllParamNull(Object... param) {
        for (Object string : param) {
            if (isNull(string)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 浮点数转换保留几位小数
     * @param value 传入的值
     * @param length 保留几位小数
     * @return
     */
    public synchronized static Double formatDouble(Double value, Integer length){
        if(length == null || length.intValue() == 0)//如果传入长度为空初始化
            length = 1;

        BigDecimal  df = new BigDecimal(value + "");

        return df.setScale(length, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 计算含税价
     * @param value 计算价格
     * @param rate 税率
     * @param taxType 0计算不含税 1计算含税
     * @return
     */
    public synchronized static Double calcTaxPrice(Double value, Double rate, Integer taxType){
        if (isAllParamNull(value, rate, taxType))
            return 0.0;

        rate = (100 + rate) / 100;//计算税率
        if (taxType == 0) {//计算不含税除法
            value = formatDouble(divide(value, rate).doubleValue(), 2);
        } else if (taxType == 1) {//计算不含税乘法
            value = formatDouble(multiply(value, rate).doubleValue(), 2);
        }
        return value;
    }
    public static void main(String[] args){
        System.out.println(validatorPhone("123245"));
        System.out.println(validatorPhone("13452052011"));
        System.out.println(formatDouble(386.7, 0, 3));
    }
    /**
     * 浮点数转换保留几位小数
     * @param value 传入的值
     * @param length 保留几位小数
     * @return
     */
    public synchronized static Double formatDouble(Double value, Integer length, Integer roundType){
        if(length == null || length.intValue() == 0)//如果传入长度为空初始化
            length = 1;

        BigDecimal  df = new BigDecimal(value + "");

        if (roundType == 0)
            return df.setScale(length, RoundingMode.HALF_UP).doubleValue();
        else if (roundType == 1)
            return df.setScale(length, RoundingMode.DOWN).doubleValue();
        else if (roundType == 3)
            return df.setScale(0, RoundingMode.HALF_UP).doubleValue();
        else
            return df.intValue() * 1.0;
    }

    /**
     * 减法运算
     * @param val1
     * @param val2
     * @return
     */
    public synchronized static BigDecimal subtract(Double val1, Double val2) {
        BigDecimal big1 = new BigDecimal(convertString(val1));
        BigDecimal big2 = new BigDecimal(convertString(val2));
        return big1.subtract(big2);
    }

    /**
     * 乘法运算
     * @param val1
     * @param val2
     * @return
     */
    public synchronized static BigDecimal multiply(Double val1, Double val2) {
        BigDecimal big1 = new BigDecimal(convertString(val1));
        BigDecimal big2 = new BigDecimal(convertString(val2));
        return big1.multiply(big2);
    }

    /**
     * 除法运算
     * @param val1
     * @param val2
     * @return
     */
    public synchronized static BigDecimal divide(Double val1, Double val2) {
        BigDecimal big1 = new BigDecimal(convertString(val1));
        BigDecimal big2 = new BigDecimal(convertString(val2));
        return big1.divide(big2);
    }

    /**
     * 判断object类型是否为空
     * @param object
     * @return
     */
    public synchronized static boolean isNull(Object object){
        if(object == null ) {
            return true;
        } else {
            if (object instanceof String) {
                if (object.toString().equals(""))
                    return true;
            }
            return false;
        }
    }

    /**
     * 字符串处理乱码
     * @param object 需要转换的乱码字符
     * @param oldEncoding 原编码格式
     * @param encoding 需要转换的编码格式
     * @return
     */
    public synchronized static String encodingString(Object object, String oldEncoding, String encoding){
        if(!isNull(object)){
            try {
                String result = new String(object.toString().getBytes(oldEncoding),encoding);
                return result;
            } catch (Exception e){
                return "";
            }
        } else {
            return "";
        }
    }

    /**
     * 集合转换成json数组
     * @param list
     * @return
     */
    public synchronized static JSONArray convertJsonArray(List<String> list) {
        if (isNull(list) || list.size() == 0)
            return null;

        JSONArray jsonArray = new JSONArray();
        for (String key : list) {
            jsonArray.add(key);
        }
        return jsonArray;
    }

    /**
     * 字符串转换集合
     * @param json
     * @return
     */
    public synchronized static List<String> convertList(String json){
        if (isNull(json))
            return null;

        JSONArray jsonArray = JSON.parseArray(json);
        List<String> resultList = new ArrayList<String>();
        for (int i = 0; i < jsonArray.size(); i++) {
            if (!isNull(jsonArray.get(i)))
                resultList.add(jsonArray.getString(i));
        }
        return resultList;

    }

    /**
     * 判断字符串是否包含重复字符
     * @param str
     * @return
     */
    public synchronized static boolean containRepeatChar(String str){
        if(str==null||str.isEmpty()){
            return false;
        }
        char[] elements=str.toCharArray();
        for(char e:elements){
            if(str.indexOf(e)!=str.lastIndexOf(e)){
                return true;
            }
        }
        return false;
    }


    /**
     * 将json数组转为List集合
     * @param str
     * @return
     */
    public synchronized static List<Map<String, Object>> convertListMap(String str) {
        if (StringUtils.isNull(str))
            return null;
        JSONArray jsonArray = JSON.parseArray(str);
        List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            resultList.add(convertMap(jsonObject.toString()));
        }
        return resultList;
    }

    /**
     * 将list集合转为JSON数组
     * @param list
     * @return
     */
    public synchronized static JSONArray convertJSONArray(List<Map<String, Object>> list){
        if(list == null || list.size() == 0)
            return null;

        JSONArray jsonArray = new JSONArray();
        for (Map<String, Object> map : list){
            jsonArray.add(map);
        }

        return jsonArray;
    }

    /**
     * json字符串转Map 对象
     * @param jsonStr
     * @return
     */
    public synchronized static Map<String, Object> aliConvertMap(String jsonStr) {
        if (isNull(jsonStr))
            return null;

        Map<String, Object> jsonMap = new HashMap<String, Object>();
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        for (Iterator iterator = jsonObject.keySet().iterator(); iterator.hasNext();) {
            Object key = iterator.next();
            jsonMap.put(convertString(key), jsonObject.get(StringUtils.convertString(key)));
        }
        return jsonMap;
    }

    /**
     * json字符串转Map 对象
     * @param jsonStr
     * @return
     */
    public synchronized static Map<String, Double> aliConvertDoubleMap(String jsonStr) {
        if (isNull(jsonStr))
            return null;

        Map<String, Double> jsonMap = new HashMap<>();
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        for (Iterator iterator = jsonObject.keySet().iterator(); iterator.hasNext();) {
            Object key = iterator.next();
            jsonMap.put(convertString(key), jsonObject.getDouble(StringUtils.convertString(key)));
        }
        return jsonMap;
    }

    /**
     * Map 转JSON字符串
     * @param jsonStr
     * @return
     */
    public synchronized static Map<String, List<Map<String, Object>>> aliConvertObjectListMap(String jsonStr) {
        if (isNull(jsonStr))
            return null;

        Map<String, List<Map<String, Object>>> jsonMap = new HashMap<>();
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        for (Iterator iterator = jsonObject.keySet().iterator(); iterator.hasNext();) {
            Object key = iterator.next();
            jsonMap.put(convertString(key), aliConvertListMap(jsonObject.getString(StringUtils.convertString(key))));
        }
        return jsonMap;
    }

    /**
     * Map 转JSON字符串
     * @param jsonMap
     * @return
     */
    public synchronized static String aliConvertListJSONObject(Map<String, List<Map<String, Object>>> jsonMap) {
        if (jsonMap == null || jsonMap.keySet().size() == 0)
            return null;
        JSONObject jo = new JSONObject();
        for (String key : jsonMap.keySet()) {
            jo.put(key, aliConvertJSONArray(jsonMap.get(key)));
        }
        return jo.toString();
    }

    /**
     * Map 转JSON字符串
     * @param jsonMap
     * @return
     */
    public synchronized static String aliConvertJSONObject(Map<String, Object> jsonMap) {
        if (jsonMap == null || jsonMap.keySet().size() == 0)
            return null;
        JSONObject jo = new JSONObject();
        for (String key : jsonMap.keySet()) {
            jo.put(key, jsonMap.get(key));
        }
        return jo.toString();
    }

    /**
     * Map 转JSON字符串
     * @param jsonMap
     * @return
     */
    public synchronized static String aliConvertDoubleJSONObject(Map<String, Double> jsonMap) {
        if (jsonMap == null || jsonMap.keySet().size() == 0)
            return null;
        JSONObject jo = new JSONObject();
        for (String key : jsonMap.keySet()) {
            jo.put(key, jsonMap.get(key));
        }
        return jo.toString();
    }

    /**
     * 集合转json字符串
     * @param listMap
     * @return
     */
    public synchronized static String aliConvertJSONArray(List<Map<String, Object>> listMap) {
        if (listMap == null || listMap.size() == 0)
            return null;

        JSONArray jsonArray = new JSONArray();
        for (Map<String,Object> map : listMap) {
            JSONObject jsonObject = JSONObject.parseObject(aliConvertJSONObject(map));
            jsonArray.add(jsonObject);
        }
        return jsonArray.toString();
    }

    /**
     * 集合转json字符串
     * @param listMap
     * @return
     */
    public synchronized static String aliConvertDoubleJSONArray(List<Map<String, Double>> listMap) {
        if (listMap == null || listMap.size() == 0)
            return null;

        JSONArray jsonArray = new JSONArray();
        for (Map<String,Double> map : listMap) {
            JSONObject jsonObject = JSONObject.parseObject(aliConvertDoubleJSONObject(map));
            jsonArray.add(jsonObject);
        }
        return jsonArray.toString();
    }

    /**
     * 将json字符串转为集合
     * @param jsonStr
     * @return
     */
    public synchronized static List<Map<String, Object>> aliConvertListMap(String jsonStr) {
        if (isNull(jsonStr))
            return null;
        List<Map<String, Object>> listMap = new ArrayList<>();
        JSONArray jsonArray = JSONArray.parseArray(jsonStr);
        for (int i = 0; i < jsonArray.size(); i++) {
            if (!isNull(jsonArray.get(i)))
                listMap.add(aliConvertMap(jsonArray.getString(i)));
        }
        return listMap;
    }

    /**
     * 将object类型转为int类型
     * @param object
     * @return
     */
    public synchronized static int convertInteger(Object object) {
        if(isNull(object)) {
            return 0;
        } else {
            return Integer.parseInt(object.toString());
        }
    }



    /**
     * json字符串转Map 对象
     * @param jsonStr
     * @return
     */
    public synchronized static Map<String, Object> convertMap(String jsonStr) {
        if(!isNull(jsonStr)){
            JSONObject jo = JSONObject.parseObject(jsonStr);
            Map<String, Object> jsonMap = new HashMap<String, Object>();
            for (String key : jo.keySet()) {
                jsonMap.put(key, jo.get(key));
            }
            return jsonMap;
        } else {
            return null;
        }
    }

    /**
     * Map 转JSON对象
     * @param jsonMap
     * @return
     */
    public synchronized static JSONObject convertJSONObject(Map<String, Object> jsonMap) {
        if(jsonMap != null && jsonMap.keySet().size() > 0) {
            JSONObject jo = new JSONObject();
            for (String key : jsonMap.keySet()) {
                jo.put(key, jsonMap.get(key));
            }
            return jo;
        } else {
            return null;
        }
    }

    /**
     * 将object类型转为Double类型
     * @param object
     * @return
     */
    public synchronized static Double convertDouble(Object object) {
        if(isNull(object)) {
            return 0.0;
        } else {
            return Double.valueOf(object.toString());
        }
    }
    
    /**
     * 将object类型转为浮点类型
     * @param object
     * @return
     */
    public synchronized static Float convertFloat(Object object) {
        if(object == null || !(object instanceof Float)) {
            return 0F;
        } else {
            return Float.valueOf(object.toString());
        }
    }

    /**
     * 将object类型转为Long类型
     * @param object
     * @return
     */
    public synchronized static Long convertLong(Object object) {
        if(object == null) {
            return 0L;
        } else {
            return Long.valueOf(object.toString());
        }
    }

    /**
     * 将object类型转为字符串类型
     * @param object
     * @return
     */
    public synchronized static String convertString(Object object) {
        if(object == null){
            return "";
        } else {
            return object.toString();
        }
    }

    /**
     * 将json对象转换为Map对象
     * @param jsonStr json字符串
     * @param str json数据key值
     * @return Map集合
     */
    public synchronized static Map<String, Object> getMap(String jsonStr, String[] str) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);//将json字符串转换为json对象
        for (String s : str) {
            if(!isNull(s)){
                resultMap.put(s, jsonObject.get(s));
            }
        }
        return resultMap;
    }

    /**
     * 将json对象转换为Map对象
     * @param jsonObject json字符串对象
     * @param str json数据key值
     * @return Map集合
     */
    public synchronized static Map<String, Object> getMap(JSONObject jsonObject, String[] str) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        for (String s : str) {
            if(!isNull(s)){
                resultMap.put(s, jsonObject.get(s));
            }
        }
        return resultMap;
    }

    /**
     * 判断多个字符串是否为空
     * @param strings
     * @return
     */
    public synchronized static boolean areNotEmpty(String... strings) {
        if (strings == null || strings.length == 0)
            return false;

        for (String string : strings) {
            if (string == null || "".equals(string)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断多个字符是否为空
     * @param strings 多个字符串，用逗号隔开
     * @return
     */
    public synchronized static boolean areNotBlank(String... strings) {
        if (strings == null || strings.length == 0)
            return false;

        for (String string : strings) {
            if (string == null || "".equals(string.trim())) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断去掉空格后的字符串是否为空
     * @param string
     * @return
     */
    public synchronized static boolean isNotBlank(String string) {
        if (string == null || string.trim().equals("") || string.length() == 0)
            return false;
        return string != null && !string.trim().equals("");
    }

    public synchronized static boolean isBlank(String string) {
		return string == null || string.trim().equals("") || string.toLowerCase().equals("undefined");
    }

    public synchronized static long toLong(String value, Long defaultValue) {
        try {
            if (value == null || "".equals(value.trim()))
                return defaultValue;
            value = value.trim();
            if (value.startsWith("N") || value.startsWith("n"))
                return -Long.parseLong(value.substring(1));
            return Long.parseLong(value);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 字符串转数字
     * @param value 字符串
     * @param defaultValue 默认数字
     * @return
     */
    public synchronized static Integer toInt(String value, Integer defaultValue) {
        try {
            if (value == null || "".equals(value.trim()))
                return defaultValue;
            value = value.trim();
            if (value.startsWith("N") || value.startsWith("n"))
                return -Integer.parseInt(value.substring(1));
            return Integer.parseInt(value);
        } catch (Exception e) {
        }
        return defaultValue;
    }

    public synchronized static BigInteger toBigInteger(String value, BigInteger defaultValue) {
        try {
            if (value == null || "".equals(value.trim()))
                return defaultValue;
            value = value.trim();
            if (value.startsWith("N") || value.startsWith("n"))
                return new BigInteger(value).negate();
            return new BigInteger(value);
        } catch (Exception e) {
        }
        return defaultValue;
    }

    public synchronized static boolean match(String string, String regex) {
        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(string);
        return matcher.matches();
    }

    /**
     * 判断是否是数字
     * @param str 字符
     * @return
     */
    public synchronized static boolean isNumeric(String str) {
        if (str == null)
            return false;
        for (int i = str.length(); --i >= 0;) {
            int chr = str.charAt(i);
            if (chr < 48 || chr > 57)
                return false;
        }
        return true;
    }

    /**
     * html 转译
     * @param text
     * @return
     */
    public synchronized static String escapeHtml(String text) {
        if (isBlank(text))
            return text;

        return text.replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;").replace("'", "&#x27;").replace("/", "&#x2F;");
    }

    /**
     * 车牌号验证
     * @param value 车牌号
     * @return
     */
    public static Boolean validatorCarNo(String value) {
        if (!org.springframework.util.StringUtils.hasText(value))
            return false;
        if (value.length() == 7) {
            Pattern pattern = Pattern.compile(carNumber);
            /**匹配正则**/
            Matcher matcher = pattern.matcher(value.toUpperCase());
            return matcher.matches();
        } else if (value.length() == 8) {
            Pattern pattern = Pattern.compile(carNewNumber.toUpperCase());
            /**匹配正则**/
            Matcher matcher = pattern.matcher(value);
            return matcher.matches();
        } else {
            return false;
        }

    }

    /**
     * 电话号码验证
     * @param value 电话号码
     * @return
     */
    public static Boolean validatorPhone(String value) {
        if (!org.springframework.util.StringUtils.hasText(value))
            return false;
        Pattern pattern = Pattern.compile(phoneNumber);
        /**匹配正则**/
        Matcher matcher = pattern.matcher(value);
        return matcher.matches();
    }

    /**
     * 邮箱验证
     * @param value 邮箱
     * @return
     */
    public static Boolean validatorDouble(String value) {
        if (!org.springframework.util.StringUtils.hasText(value))
            return false;
        Pattern pattern = Pattern.compile(doubleNumber);
        /**匹配正则**/
        Matcher matcher = pattern.matcher(value);
        return matcher.matches();
    }

    /**
     * 浮点小数验证
     * @param value 浮点数
     * @return
     */
    public static Boolean validatorEmail(String value) {
        if (!org.springframework.util.StringUtils.hasText(value))
            return false;
        Pattern pattern = Pattern.compile(email);
        /**匹配正则**/
        Matcher matcher = pattern.matcher(value);
        return matcher.matches();
    }

    /**
     * IP验证
     * @param value IP地址
     * @return
     */
    public static Boolean validatorIP(String value) {
        if (!org.springframework.util.StringUtils.hasText(value))
            return false;
        Pattern pattern = Pattern.compile(ip);
        /**匹配正则**/
        Matcher matcher = pattern.matcher(value);
        return matcher.matches();
    }

    /**
     * 返回一个定长的随机字符串(只包含小写字母、数字)
     * @param length 随机字符串长度
     * @return 随机字符串
     */
    public static String genLetterString(Integer length) {
        StringBuffer sb = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(nletterchar.charAt(random.nextInt(nletterchar.length())));
        }
        return sb.toString();
    }
    /**
     * 返回一个定长的随机字符串(只包含大小写字母、数字)
     * @param length 随机字符串长度
     * @return 随机字符串
     */
    public static String generateString(int length) {
        StringBuffer sb = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(allChar.charAt(random.nextInt(allChar.length())));
        }
        return sb.toString();
    }

    /**
     * 返回一个定长的随机纯字母字符串(只包含大小写字母)
     * @param length 随机字符串长度
     * @return 随机字符串
     */
    public static String generateMixString(int length) {
        StringBuffer sb = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(allChar.charAt(random.nextInt(letterChar.length())));
        }
        return sb.toString();
    }

    /**
     * 返回一个定长的随机纯大写字母字符串(只包含大小写字母)
     * @param length 随机字符串长度
     * @return 随机字符串
     */
    public static String generateLowerString(int length) {
        return generateMixString(length).toLowerCase();
    }

    /**
     * 返回一个定长的随机纯小写字母字符串(只包含大小写字母)
     * @param length 随机字符串长度
     * @return 随机字符串
     */
    public static String generateUpperString(int length) {
        return generateMixString(length).toUpperCase();
    }

    /**
     * 生成一个定长的纯0字符串
     * @param length 字符串长度
     * @return 纯0字符串
     */
    public static String generateZeroString(int length) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            sb.append('0');
        }
        return sb.toString();
    }

    /**
     * 根据数字生成一个定长的字符串，长度不够前面补0
     *
     * @param num 数字
     * @param fixedLength 字符串长度
     * @return 定长的字符串
     */
    public static String toFixedLengthString(long num, int fixedLength) {
        StringBuffer sb = new StringBuffer();
        String strNum = String.valueOf(num);
        if (fixedLength - strNum.length() >= 0) {
            sb.append(generateZeroString(fixedLength - strNum.length()));
        } else {
            throw new RuntimeException("将数字" + num + "转化为长度为" + fixedLength
                    + "的字符串发生异常！");
        }
        sb.append(strNum);
        return sb.toString();
    }

    /**
     * 根据数字生成一个定长的字符串，长度不够前面补0
     * @param num 数字
     * @param fixedLength 字符串长度
     * @return 定长的字符串
     */
    public static String toFixedLengthString(Integer num, Integer fixedLength) {
        StringBuffer sb = new StringBuffer();
        String strNum = String.valueOf(num);
        if (fixedLength - strNum.length() >= 0) {
            sb.append(generateZeroString(fixedLength - strNum.length()));
        } else {
            throw new RuntimeException("将数字" + num + "转化为长度为" + fixedLength
                    + "的字符串发生异常！");
        }
        sb.append(strNum);
        return sb.toString();
    }

	/**
	 * 验证字符串是否为符合该相应格式的日期字符串
	 * @param dateStr		时期字符串
	 * @param pattern		日期格式
	 * @return
	 */
    public static Boolean validatorDate(String dateStr, String pattern) {
    	if(isBlank(dateStr)){
    		return false;
		}
		if (isBlank(pattern)) {
			pattern = "yyyy-MM-dd HH:mm:ss";
		}
		try {
			DateFormat sdf = new SimpleDateFormat(pattern);
			sdf.setLenient(false);
			sdf.parse(dateStr);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static Boolean validatorDate2(String dateStr, String... patterns) {
		if (isBlank(dateStr)) {
			return false;
		}
		if (patterns == null || patterns.length < 1) {
			patterns = DateUtil.DEFAULT_FORMAT_PATTERS;
		}
		for (String pattern : patterns) {
			try {
				DateFormat sdf = new SimpleDateFormat(pattern);
				sdf.setLenient(false);
				sdf.parse(dateStr);
				return true;
			} catch (Exception e) {
				// e.printStackTrace();
				continue;
			}
		}
		return false;
	}
    /**
     * double类型的加法运算（不需要舍入）
     * @param d1
     * @param d2
     * @return 不加doubleValue()则, 返回BigDecimal对象
     */
    public static double addDouble(double d1, double d2) {
        BigDecimal p1 = new BigDecimal(Double.toString(d1));
        BigDecimal p2 = new BigDecimal(Double.toString(d2));
        return p1.add(p2).doubleValue();
    }


    /**
     * double类型的减法运算
     * @param d1
     * @param d2
     * @return 不加doubleValue()则, 返回BigDecimal对象
     */
    public static double subtractDouble(double d1, double d2) {
        BigDecimal p1 = new BigDecimal(Double.toString(d1));
        BigDecimal p2 = new BigDecimal(Double.toString(d2));
        return p1.subtract(p2).doubleValue();
    }

    /**
     * double类型的减法运算（需要舍入）
     * @param d1
     * @param d2
     * @param scale  保留scale位小数
     * @return  不加doubleValue()则, 返回BigDecimal对象
     */
    public static double subtractDouble(double d1, double d2, int scale) {
        BigDecimal p1 = new BigDecimal(Double.toString(d1));
        BigDecimal p2 = new BigDecimal(Double.toString(d2));
        return p1.subtract(p2).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * double类型的乘法运算
     *
     * @param d1
     * @param d2
     * @return 不加doubleValue()则, 返回BigDecimal对象
     */
    public static Double multiplyDouble(double d1, double d2) {
        BigDecimal p1 = new BigDecimal(Double.toString(d1));
        BigDecimal p2 = new BigDecimal(Double.toString(d2));
        return p1.multiply(p2).doubleValue();
    }
    public static Double divideDouble(double d1, double d2, int scale) {
        if (scale < 0 || isNull(d1) || isNull(d2)) {
            return 0.0;
        }
        BigDecimal p1 = new BigDecimal(Double.toString(d1));
        BigDecimal p2 = new BigDecimal(Double.toString(d2));
        return p1.divide(p2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * double类型的超大数值的除法运算（需要舍入）
     * @param d1
     * @param d2
     * @param scale 保留scale位小数
     * @return 返回字符串，不然double数字会转成科学计数法显示
     */
    public static String divideDoubleToStr(double d1, double d2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("Parameter error");
        }
        BigDecimal p1 = new BigDecimal(Double.toString(d1));
        BigDecimal p2 = new BigDecimal(Double.toString(d2));
        return p1.divide(p2, scale, BigDecimal.ROUND_HALF_UP).toPlainString();
    }

	/**
	 * 验证企业税号
	 *
	 * @param taxNumber
	 * @return
	 */
	public static boolean validTaxCode(String taxNumber) {
		// 长度必须是18位
		if (taxNumber == null || taxNumber.length() != 18) {
			return false;
		}
		// 检查是否只包含数字和字母（不包含I、O、S、V、Z）
		for (int i = 0; i < taxNumber.length(); i++) {
			char c = taxNumber.charAt(i);
			if (!Character.isDigit(c) && !(c >= 'A' && c <= 'H') && !(c >= 'J' && c <= 'N') && !(c >= 'P' && c <= 'Y')) {
				return false;
			}
		}
		// 如果需要更严格的校验（例如使用校验码算法），可以在这里添加
		// 默认情况下，只进行基本格式校验
		return true;
	}

	// 校验18位身份证号码的方法
	public static boolean validIDCard18(String idCard) {
		// 1. 格式校验
		if (idCard == null || !idCard.matches(ID_CARD_REGEX)) {
			return false;
		}
		return true;
	}

	/**
	 * 验证身份证号
	 *
	 * @param idCard
	 * @return
	 */
	@Deprecated
	public static boolean validIDCard18Old(String idCard) {
		if (idCard == null || idCard.length() != 18) {
			return false;
		}
		// 检查最后一位是否为数字或'X'
		char lastChar = idCard.charAt(17);
		if (!(lastChar >= '0' && lastChar <= '9' || lastChar == 'X' || lastChar == 'x')) {
			return false;
		}
		// 这里可以添加更严格的校验逻辑，比如校验码的验证等
		// ...
		return true;
	}

	/**
	 * 提取文字中的价格
	 *
	 * @param text
	 * @return
	 */
	public static Double tranMoney(String text) {
		if (isBlank(text)) {
			return 0d;
		}
		Double res = 0d;
		// 去掉最后一个小数点
		text = removeExtraDots(text);
		text = text.replaceAll("\\s+", "");
		text = text.replaceAll(",", "");
		boolean numeric = StringUtils.isNumeric(text);
		if (numeric) {
			// 是纯数字
			res = Double.valueOf(text);
			return res;
		}
		// 使用正则表达式匹配￥后面的数字，包括逗号和小数点
		List<String> regexList = new ArrayList<>();
		regexList.add("￥(\\d+(\\.\\d+)?)");
		regexList.add("RMB(\\d+(\\.\\d+)?)");
		regexList.add("\\d+(\\.\\d+)?");
		//	转换为大写
		text = text.toUpperCase();
		for (String regex : regexList) {
			res = matchDouble(text, regex);
			if (res != null) {
				break;
			}
		}
		return res;
	}

	private static Double matchDouble(String text, String regex) {
		if (isBlank(text) || isBlank(regex)) {
			return null;
		}
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(text);
		if (matcher.find()) {
			// 提取第一个匹配项
			String money = matcher.group();
			money = money.replaceAll("￥", "");
			money = money.replaceAll("RMB", "");
			Double res = Double.valueOf(money);
			return res;
		}
		return null;
	}

	/**
	 * 去除除了最后一个小数点外的小数点
	 *
	 * @param str
	 * @return
	 */
	public static String removeExtraDots(String str) {
		return str.replaceAll("\\.*\\.(?=.*\\.)", "");
	}

	/**
	 * 将数字转为中文大写
	 *
	 * @param number
	 * @return
	 */
	public static String toMoneyUpperCase(Double number) {
		if (number == null) {
			return "";
		}
		String prefix = "";
		if (number < 0) {
			prefix = "负";
			number = Math.abs(number);
		}
		//取消科学记数法
		NumberFormat numFormat = NumberFormat.getInstance();
		numFormat.setMaximumFractionDigits(2);//设置小数位个数
		numFormat.setGroupingUsed(false);//取消科学技术发
		String formatNum = numFormat.format(number);
		String strmoney = formatNum + "";//浮点型转为字符型
		String lastUpNum = "null"; //用于存放上个参数的值
		String result = "";//返回的结果
		String[] split = strmoney.split("\\.");
		String strMoney = split[0];
		String point = "";
		//小数部分取值处理。
		if (split.length > 1) {
			point = split[1];
			if (point.length() == 1) {
				point = point.concat("0");
			}
		} else {
			point = "0";
		}
		//大于12位就直接返回。
		int moneyLen = strMoney.length();
		if (number == 0) {
			return "零圆整";
		}
		if (moneyLen > 12) {
			return "金额：" + number + "元，超出大写转换范围。最大金额：999999999999.99元";
		}
		//整数(integer)部分处理。
		if (!"0".equals(strMoney)) {
			for (int i = 0; i < moneyLen; i++) {
				String strNum = strMoney.charAt(i) + "";
				int singleNum = Integer.parseInt(strNum);
				String upSingleNum = upNum[singleNum];
				//上一为不等于0的情况
				if (!"零".equals(lastUpNum)) {
					if (!"零".equals(upSingleNum)) {
						result = result.concat(upSingleNum).concat(danwei[moneyLen - i - 1]);
					} else
						//为零但是在万、亿位上要加单位 (moneyLen-i)==9 指的是单位：亿。  (moneyLen-i)==5指的是单位：万
						if ((moneyLen - i) == 5 || (moneyLen - i) == 9) {
							lastUpNum = "";
						} else {
							result = result.concat(upSingleNum);
						}
				}
				//上一位为0的情况
				if ("零".equals(lastUpNum) && !"零".equals(upSingleNum)) {
					result = result.concat(upSingleNum).concat(danwei[moneyLen - i - 1]);
				}
				//捕捉上一位数（lastUpNum）为零的情况做优化。
				if ((moneyLen - i) == 5 || (moneyLen - i) == 9) {
					//排除加单位时前面为"零"的情况。如：两百零万
					if ("零".equals(lastUpNum) || "null".equals(lastUpNum)) {
						result = result.substring(0, result.length() - 1);
					}
					if (!result.endsWith("亿")) {
						result = result.concat(danwei[moneyLen - i - 1]);
					}
					lastUpNum = "";
				} else {
					//把当前大写数字复制给 lastUpNum 用于下次判断
					lastUpNum = upSingleNum;
				}
			}
			//对几万元整和几亿元整(result:五万零或者五亿零零)做优化。
			result = result.replaceAll("零零", "零");
			if (result.endsWith("零")) {
				String substring = result.substring(0, result.length() - 1);
				result = substring;
			}
			result = result.concat("圆");
			result = result.replaceAll("圆圆", "圆");
			result = result.replaceAll("万万", "万");

		}

		//小数(point)部分处理
		if ("0".equals(point)) {
			result = result + "整";
		} else {
			//去 整
//            if(result.endsWith("整")){
//                result = result.substring(0,result.length()-1);
//            }
			if ((point.charAt(0) + "").equals("0")) {
				result = result.concat(upNum[Integer.parseInt(point.charAt(1) + "")] + "分");
			} else if ((point.charAt(1) + "").equals("0")) {
				result = result.concat(upNum[Integer.parseInt(point.charAt(0) + "")] + "角");
			} else {
				result = result.concat(upNum[Integer.parseInt(point.charAt(0) + "")] + "角").concat(upNum[Integer.parseInt(point.charAt(1) + "")] + "分");
			}
		}
		result = prefix + result;
		return result;
	}

    /**
     * map生成对象
     * @param map
     * @param clazz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> T mapToObject(Map<String, Object> map, Class<T> clazz) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        // Convert Map to JSON string
        String jsonString = mapper.writeValueAsString(map);
        // Convert JSON string to Java object
        return mapper.readValue(jsonString, clazz);
    }


    /**
     * 转换集合
     * @param mapList
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> fastClassList(List<Map<String, Object>> mapList, Class<T> clazz) {
        if (mapList == null || mapList.size() == 0)
            return null;
        List<T> list = new ArrayList<>();
        for (int i = 0; i < mapList.size(); i++) {
            Map<String, Object> map = mapList.get(i);
            T obj = fastClass(map, clazz);
            if (obj == null)
                continue;
            list.add(obj);
        }
        return list;
    }
    public static <T> T fastClass(Map<String, Object> map, Class<T> clazz) {
        if(map == null || map.keySet().size() == 0)
            return null;
        String s = JSON.toJSONString(map);
        T object = JSON.parseObject(s, clazz);
        return object;
    }
    /**
     * 获取字符串的最后一个数字
     * @param strValue
     * @return
     */
    public static int getLastNum(String strValue) {
        int num = 0;
        if(isBlank(strValue)){
            return num;
        }
        String pattern = "[0-9]+$";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(strValue);
        if (m.find()) {
            String group = m.group();
            num = Integer.valueOf(group);
        }
        return num;
    }
}
